package mediaCoreLib.core
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.net.URLRequest;
	
	[Event(name="complete", type="flash.events.Event")]
	[Event(name="ioError", type="flash.events.IOErrorEvent")]
	[Event(name="soundComplete", type="flash.events.Event")]
	
	[ExcludeClass]
	public class PlaylistObject extends EventDispatcher
	{
		///////////////////////////////////////////////////////
		//	CONSOLE
		///////////////////////////////////////////////////////
		
		public function play ():void
		{
			if (!isLoaded && !_sound.hasEventListener(Event.COMPLETE))
				_sound.addEventListener(Event.COMPLETE, onComplete_doPlay);
			
			else if (isLoaded && !isPlaying)
			{
				if (_channel && _channel.hasEventListener(Event.SOUND_COMPLETE))
					_channel.removeEventListener(Event.SOUND_COMPLETE, onSoundComplete);
				
				_channel = _sound.play(_currentPosition);
				_channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);
				
				_isPlaying = true;
				dispatchEvent(new Event("isPlayingChanged"));
			}
			
			else
				_isPlaying = true;
		}
		
		public function pause ():void
		{
			_currentPosition = _channel.position;
			_channel.stop();
			
			_isPlaying = false;
		}
		
		public function stop ():void
		{
			_currentPosition = 0;
			_channel.stop();
			
			_isPlaying = false;
		}
		
		///////////////////////////////////////////////////////
		//	MISC. EVT HANDLERS
		///////////////////////////////////////////////////////
		
		private function onComplete_doPlay (evt:Event):void
		{
			_sound.removeEventListener(Event.COMPLETE, onComplete_doPlay);
			play();
		}
		
		private function onSoundComplete (evt:Event):void
		{
			evt.target.removeEventListener(Event.SOUND_COMPLETE, onSoundComplete);
			
			_isPlaying = false;
			dispatchEvent(evt);
		}
		
		///////////////////////////////////////////////////////
		//	URL
		///////////////////////////////////////////////////////
		
		private var _url:String;
		
		public function get url ():String
		{
			return _url;
		}
		
		public function set url (value:String):void
		{
			if (_url != value)
			{
				_url = value;
				
				//if old sound, clear its listeners that may have not completed
				if (_sound)
				{
					_sound.removeEventListener(Event.COMPLETE, onComplete);
					_sound.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
				}
				
				var request:URLRequest = new URLRequest(_url);
				
				_sound = new Sound();
				
				_sound.addEventListener(Event.COMPLETE, onComplete);
				_sound.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
				_sound.load(request);
			}
		}
		
		///////////////////////////////////////////////////////
		//	IS PLAYING
		///////////////////////////////////////////////////////
		
		private var _isPlaying:Boolean = false;
		
		public function get isPlaying ():Boolean
		{
			return _isPlaying;
		}
		
		///////////////////////////////////////////////////////
		//	CURRENT POSITION
		///////////////////////////////////////////////////////
		
		private var _currentPosition:int;
		
		public function get currentPosition ():int
		{
			return _currentPosition;
		}
		
		///////////////////////////////////////////////////////
		//	IS LOADED
		///////////////////////////////////////////////////////
		
		private var _isLoaded:Boolean;
		
		public function get isLoaded ():Boolean
		{
			return _isLoaded;
		}
		
		///////////////////////////////////////////////////////
		//	SOUND
		///////////////////////////////////////////////////////
		
		private var _sound:Sound;
		private var _channel:SoundChannel;
		
		public function get sound ():Sound
		{
			return _sound;
		}
		
		///////////////////////////////////////////////////////
		//	EVT HANDLERS
		///////////////////////////////////////////////////////
		
		private function onComplete (evt:Event):void
		{
			_isLoaded = true;
			
			_sound.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
			_sound.removeEventListener(Event.COMPLETE, onComplete);
			
			dispatchEvent(new Event(Event.COMPLETE));
		}
		
		private function onIOError (evt:IOErrorEvent):void
		{
			_isLoaded = false;
			
			_sound.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
			_sound.removeEventListener(Event.COMPLETE, onComplete);
			
			dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
		}
	}
}